package facade

import (
	"context"
	"github.com/go-kratos/kratos/v2/log"
	"github.com/jinzhu/copier"
	"google.golang.org/protobuf/types/known/emptypb"
	command_service "gotham-plan-manage/internal/app/command_service"
	"gotham-plan-manage/internal/app/query_service"
	"gotham-plan-manage/internal/interfaces/assembler"
	"gotham-plan-manage/proto/gotham-plan-manage-proto/task"
)

/*
   @author:zhongyang
   @date:2023/5/31
   @description:待办-接口层
*/

type TaskServer struct {
	task.UnimplementedTodoTaskApiServer
	commandService *command_service.PlanManageCommandService
	queryService   *query_service.PlanManageQueryService
	taskAssembler  assembler.PlanManageAssembler
	logger         *log.Helper
}

func NewTaskServer(commandService *command_service.PlanManageCommandService, queryService *query_service.PlanManageQueryService, logger log.Logger) *TaskServer {
	return &TaskServer{commandService: commandService, queryService: queryService, logger: log.NewHelper(logger)}
}

func (t *TaskServer) CreateItem(ctx context.Context, request *task.CreateItemRequest) (*emptypb.Empty, error) {
	createTaskCommand := t.taskAssembler.ToCommandFromCreateTaskItemRequest(request)
	err := t.commandService.CreateTaskItem(ctx, createTaskCommand)
	if err != nil {
		return nil, err
	}
	return &emptypb.Empty{}, nil
}

func (t *TaskServer) Delete(ctx context.Context, request *task.IdRequest) (*emptypb.Empty, error) {
	deleteTaskCommand := t.taskAssembler.ToCommandFromDeleteTaskById(request)
	err := t.commandService.DeleteTaskById(ctx, deleteTaskCommand)
	if err != nil {
		return nil, err
	}
	return &emptypb.Empty{}, nil
}

func (t *TaskServer) DeleteItem(ctx context.Context, request *task.IdRequest) (*emptypb.Empty, error) {
	deleteTaskItemCommand := t.taskAssembler.ToCommandFromDeleteTaskItemById(request)
	err := t.commandService.DeleteTaskItemById(ctx, deleteTaskItemCommand)
	if err != nil {
		return nil, err
	}
	return &emptypb.Empty{}, nil
}

func (t *TaskServer) GetItem(ctx context.Context, request *task.IdRequest) (*task.GetItemResponse, error) {
	getTaskItemQuery := t.taskAssembler.ToQueryFromGetTaskItemById(request)
	taskItem, err := t.queryService.GetTaskItemById(ctx, getTaskItemQuery)
	if err != nil {
		return nil, err
	}
	res := &task.GetItemResponse{}
	_ = copier.Copy(&res, taskItem)
	return res, nil
}

func (t *TaskServer) GetTaskList(ctx context.Context, request *task.GetTaskListRequest) (*task.GetTaskListResponse, error) {
	listQuery := t.taskAssembler.ToQueryFromGetTaskList(request)
	list, total, err := t.queryService.GetTaskList(ctx, listQuery)
	if err != nil {
		return nil, err
	}
	res := &task.GetTaskListResponse{
		Total:    int32(total),
		Page:     request.Page,
		PageSize: request.PageSize,
	}
	_ = copier.Copy(&res.List, list)
	return res, nil
}

func (t *TaskServer) EditItem(ctx context.Context, request *task.EditItemRequest) (*emptypb.Empty, error) {
	editTaskItemCommand := t.taskAssembler.ToCommandFromEditTaskItem(request)
	err := t.commandService.EditTaskItemById(ctx, editTaskItemCommand)
	if err != nil {
		return nil, err
	}
	return &emptypb.Empty{}, nil
}

func (t *TaskServer) FinishItem(ctx context.Context, request *task.IdRequest) (*emptypb.Empty, error) {
	finishTaskItemCommand := t.taskAssembler.ToCommandFromFinishTaskItem(request)
	err := t.commandService.FinishTaskItem(ctx, finishTaskItemCommand)
	if err != nil {
		return nil, err
	}
	return &emptypb.Empty{}, nil
}

func (t *TaskServer) SaveQuestion(ctx context.Context, request *task.SaveQuestionRequest) (*emptypb.Empty, error) {
	saveQuestionCommand := t.taskAssembler.ToCommandFromSaveQuestionRequest(request)
	err := t.commandService.SaveQuestions(ctx, saveQuestionCommand)
	if err != nil {
		return nil, err
	}
	return &emptypb.Empty{}, nil
}

func (t *TaskServer) FindOneDayQuestions(ctx context.Context, request *task.FindOneDayQuestionsRequest) (*task.FindOneDayQuestionsResponse, error) {
	findOneDayQuestionQuery := t.taskAssembler.ToQueryFromFindOneDayQuestions(request)
	questions, err := t.queryService.FindOneDayQuestions(ctx, findOneDayQuestionQuery)
	if err != nil {
		return nil, err
	}
	res := &task.FindOneDayQuestionsResponse{}
	_ = copier.Copy(&res.Questions, questions)
	return res, nil
}

func (t *TaskServer) SearchQuestions(ctx context.Context, request *task.SearchQuestionsRequest) (*task.SearchQuestionsResponse, error) {
	searchQuestionQuery := t.taskAssembler.ToQueryFromSearchQuestionRequest(request)
	questions, err := t.queryService.SearchQuestions(ctx, searchQuestionQuery)
	if err != nil {
		return nil, err
	}
	res := &task.SearchQuestionsResponse{}
	_ = copier.Copy(&res.Questions, questions)
	return res, nil
}

func (t *TaskServer) GetOngoingTaskItems(ctx context.Context, request *task.GetOngoingTaskItemsRequest) (*task.GetOngoingTaskItemsResponse, error) {
	getOngoingTasksQuery := t.taskAssembler.ToQueryFromGetOngoingTasksRequest(request)
	taskItems, err := t.queryService.GetOngoingTasks(ctx, getOngoingTasksQuery)
	if err != nil {
		return nil, err
	}
	res := &task.GetOngoingTaskItemsResponse{}
	_ = copier.Copy(&res.TaskItems, taskItems)
	return res, nil
}

func (t *TaskServer) IsFinishAllTask(ctx context.Context, request *task.IsFinishAllTaskRequest) (*task.IsFinishAllResponse, error) {
	isFinishTaskQuery := t.taskAssembler.ToQueryFromIsFinishTaskRequest(request)
	isFinishTask, err := t.queryService.IsFinishTask(ctx, isFinishTaskQuery)
	if err != nil {
		return nil, err
	}
	return &task.IsFinishAllResponse{
		IsFinish: isFinishTask,
	}, nil
}
